/**
 * 差集 A-B = Exclude
 */
export type SetDifference<A,B> = A extends B?never:A;
type A = string|number
type B = number|Boolean
type AB = SetDifference<A,B>

/**
 * Omit = Exclude+Pick 忽略某些属性 第二个参数的属性
 * SetDifference:name visible
 */
type Omit<T,K extends keyof any>=Pick<T,SetDifference<keyof T,K>>;
type Props = {
    name:string,
    age:number,
    visible:boolean
}
type OmitAgeProps = Omit<Props,'age'>
//type Props = {name:string,visible:boolean}

//Diff：省略掉一样的
namespace na{
    type Props = {
        name:string,
        age:number,
        visible:boolean
    }
    type DefaultProps = {age:number}
    type Diff<T extends object,U extends object>=Pick<T,SetDifference<keyof T,U>>;
    type DifffProps = Diff<Props,DefaultProps>
}

namespace nb{
    //InterSection 交叉属性
    type InterSection<T extends object,U extends object>=Pick<T,Extract<keyof T,keyof U>&Extract<keyof U,keyof T>>;
    type Props = {
        name:string,
        age:number,
        visible:boolean
    }
    type DefaultProps = {age:number}
    //type InterProps = Props&DefaultProps
    type DuplicateProps = InterSection<Props,DefaultProps>
}

namespace nc{
    //Overwrite
    type Diff<T extends object,U extends object>=Pick<T,SetDifference<keyof T,U>>;
    type OldProps = {name:string,age:number,visible:boolean}
    type NewProps ={age:string,other:string}
    type InterSection<T extends object,U extends object>=Pick<T,Extract<keyof T,keyof U>&Extract<keyof U,keyof T>>;
    type Overwrite<
    T extends Object,
    U extends Object,
    I=Diff<T,U>&InterSection<U,T>
    >=Pick<I,keyof I>;
    type ReplacedProps = Overwrite<OldProps,NewProps>
}

namespace nd{
    //merge = Compute + Omit<U,T>
    type O1 = {
        id:number,
        name:string
    }
    type O2 = {
        id:number,
        age:number
    }
    //type R2 = Merge<O1,O2>
    type Compute<A extends any> = A extends Function?A:{[K in keyof A]:A[K]}
    type R1 = Compute<string> 
    //type R1 = {x: 'x'; y: 'y';}

    type Merge<O1 extends object,O2 extends object> = Compute<O1&Omit<O2,keyof O1>>
    type R2 = Merge<O1,O2>

   
}